﻿using EnvControlLib;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.ServiceLocation;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;
using SurveillancePro.Base.Events;
using Microsoft.Practices.Unity;
using System.Collections.ObjectModel;
using CommonBase;
using CommonClass;
using SurveillanceLib;
using DataLib;

namespace EnvCommonUtility
{
    /// <summary>
    /// 公共静态方法与常量【与业务相关操作】
    /// </summary>
    public static class EnvUtilities
    {
        #region 静态常量属性

        /// <summary>
        /// 设备树资源
        /// </summary>
        public static ObservableCollection<ITreeGroup> TreeViewSource { get; set; }

        public static IEventAggregator EnvEventAggregator { get; set; }
        public static IRegionManager EnvRegionManager { get; set; }
        public static IServiceLocator EnvServiceLocator { get; set; }
        public static IModuleManager EnvModuleManager { get; set; }
        public static IModuleCatalog EnvModuleCatalog { get; set; }
        public static IUnityContainer EnvContainer { get; set; }

        #endregion

        #region 静态方法

        #region Private Methods

        #region 回调函数
        /// <summary>
        /// 设备断开连接处理，断线回调函数，回调出当前网络已经断开的设备, 对调用SDK的ClIENT_LogOut()函数主动断开的设备不回调
        /// </summary>
        /// <param name="lLoginID">设备用户登录句柄</param>
        /// <param name="pchDVRIP">DVR设备IP</param>
        /// <param name="nDVRPort">DVR设备连接端口</param>
        /// <param name="dwUser">用户数据</param>
        private static void _disConnectEvent(int lLoginID, StringBuilder pchDVRIP,
            int nDVRPort, IntPtr dwUser)
        {
            MessageBox.Show("设备自动断开连接！", ConstantString.MSG_COMPANY);
        }
        #endregion

        #endregion

        /// <summary>
        /// 设备树加载，获得状态可用的所有设备
        /// </summary>
        /// <returns></returns>
        public static ObservableCollection<ITreeGroup> LoadDeviceTreeData()
        {
            try
            {
                EnvTreeViewOperation _treeOpertion = new EnvTreeViewOperation()
                {
                    DisConnectAction = _disConnectEvent,
                };

                TreeGroupModel node = new TreeGroupModel(string.Empty, new ObservableCollection<ITreeGroup>());
                _treeOpertion.AddDeviceTreeView(0, node, (TreeGroupModel)null,
                    "db_VWMSConnectionString", string.Format("{0}.exe", System.Windows.Forms.Application.ProductName)); // 获取树节点，构建设备树
                EnvUtilities.TreeViewSource = node.Leaves; // 绑定到树资源

                return node.Leaves;
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
                return null;
            }
        }

        /// <summary>
        /// 停止指定窗口中的视频
        /// </summary>
        /// <param name="currPanel">要停止的 Panel</param>
        public static void StopPanelRealPlay(EnvVideoPanel currPanel)
        {
            try
            {
                if (currPanel != null && currPanel.Tag != null &&
                    currPanel.Tag is TagModel && (currPanel.Tag as TagModel).Driver_Instance != null &&
                    !string.IsNullOrWhiteSpace((currPanel.Tag as TagModel).Panel_RealPlayHandle))
                {
                    TagModel tagCurrentPanel = currPanel.Tag as TagModel;
                    if (tagCurrentPanel.Driver_Instance.StopRealPlay(tagCurrentPanel.Panel_RealPlayHandle)) // 停止实时监控，需要传递实时监控句柄
                    {
                        tagCurrentPanel.Panel_SelectedChannel = tagCurrentPanel.Panel_RealPlayHandle = string.Empty;
                        (currPanel.DataContext as ViewModel_EnvVideoPanel).CurrentPanel.Refresh(); // 刷新
                        (currPanel.DataContext as ViewModel_EnvVideoPanel).VideoInformation = string.Empty; // 不显示标题

                        if (EnvUtilities.EnvEventAggregator != null)
                        {
                            // 修改云台控制按钮状态
                            Visibility isShowPTZControlButton = Visibility.Collapsed;
                            if (currPanel != null &&
                                currPanel.Tag != null &&
                                (currPanel.Tag is TagModel) &&
                                (currPanel.Tag as TagModel).Driver_Instance != null &&
                                !string.IsNullOrWhiteSpace((currPanel.Tag as TagModel).Driver_LoginID) &&
                                !string.IsNullOrWhiteSpace((currPanel.Tag as TagModel).Panel_SelectedChannel))
                                isShowPTZControlButton = Visibility.Visible;

                            EnvUtilities.EnvEventAggregator.GetEvent<OpenModelEvent>().Publish(new OpenModelEventArg() { ModelName = "ViewModel_PTZControl", FunctionName = "ChangePTZControlState", Arg = isShowPTZControlButton, }); // 事件通知
                        }
                    }
                    else
                    {
                        MessageBox.Show(SurveillanceUtilities.STOP_REALPLAY_FAILURE, ConstantString.MSG_COMPANY);
                        return;
                    }
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 停止该窗口的视频后在另一窗口中播放
        /// </summary>
        /// <param name="panelStop">要停止的 Panel</param>
        /// <param name="panelPlay">要播放的 Panel</param>
        public static void StopAndPlay(EnvVideoPanel panelStop, EnvVideoPanel panelPlay)
        {
            try
            {
                int outChannel;
                if (panelStop.Tag != null && panelStop.Tag is TagModel &&
                    (panelStop.Tag as TagModel).Driver_Instance != null &&
                    !string.IsNullOrWhiteSpace((panelStop.Tag as TagModel).Driver_LoginID) &&
                    !string.IsNullOrWhiteSpace((panelStop.Tag as TagModel).Panel_SelectedChannel) &&
                    int.TryParse((panelStop.Tag as TagModel).Panel_SelectedChannel, out outChannel))
                {
                    TagModel panelStopTag = panelStop.Tag as TagModel;

                    // a. 先停止小窗口中的视频
                    if (!string.IsNullOrWhiteSpace((panelStop.Tag as TagModel).Panel_RealPlayHandle))
                    {
                        if (panelStopTag.Driver_Instance.StopRealPlay(panelStopTag.Panel_RealPlayHandle)) // 停止实时监控，需要传递实时监控句柄
                            panelStopTag.Panel_RealPlayHandle = string.Empty;
                        else
                        {
                            MessageBox.Show(SurveillanceUtilities.STOP_REALPLAY_FAILURE, ConstantString.MSG_COMPANY);
                            return;
                        }
                    }

                    // b. 再播放大窗口中的视频
                    string pRealPlayHandle = panelStopTag.Driver_Instance.RealPlay(panelStopTag.Driver_LoginID,
                        outChannel, (panelPlay.DataContext as ViewModel_EnvVideoPanel).CurrentPanel.Handle); // 只取数据不播放

                    // c. 得到最新的 RealPlayHandle
                    Utilities.CopyObject(panelStopTag, panelPlay.Tag);
                    (panelPlay.Tag as TagModel).Panel_RealPlayHandle = pRealPlayHandle;
                }
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 最小化视频窗口
        /// </summary>
        /// <param name="splitScreen">主界面视频窗口容器</param>
        /// <param name="maxScreen">最大化视频窗口</param>
        /// <param name="doubleAction">共同的双击事件</param>
        public static void HideMaxScreen(System.Windows.Controls.Panel splitScreen,
            EnvVideoPanel maxScreen, Action doubleAction = null)
        {
            try
            {
                if (maxScreen == null || EnvPanelOperation.SelectedPanel == null)
                    return;

                if (splitScreen != null)
                    splitScreen.Visibility = System.Windows.Visibility.Visible;
                if (maxScreen != null)
                    maxScreen.Visibility = System.Windows.Visibility.Collapsed;

                EnvUtilities.StopAndPlay(maxScreen, EnvPanelOperation.SelectedPanel);
                if ((EnvPanelOperation.SelectedPanel.DataContext as ViewModel_EnvVideoPanel).VideoInformation !=
                    (maxScreen.DataContext as ViewModel_EnvVideoPanel).VideoInformation &&
                    string.IsNullOrWhiteSpace((maxScreen.DataContext as ViewModel_EnvVideoPanel).VideoInformation)) // 最大化视频窗口与一般视频窗口标题信息不一致时
                {
                    (EnvPanelOperation.SelectedPanel.DataContext as ViewModel_EnvVideoPanel).TempInformation =
                        (EnvPanelOperation.SelectedPanel.DataContext as ViewModel_EnvVideoPanel).VideoInformation; // 记录临时信息
                    (EnvPanelOperation.SelectedPanel.DataContext as ViewModel_EnvVideoPanel).VideoInformation =
                        string.Empty; // 解决最大化窗口关闭后原视频窗口依然显示标题栏，bug: 再次切换分屏时又出现画面！
                }

                // 执行双击后的相关操作
                if (doubleAction != null)
                    doubleAction();
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 最大化视频窗口
        /// </summary>
        /// <param name="selectedPanel">当前所选视频窗口</param>
        /// <param name="splitScreen">主界面视频窗口容器</param>
        /// <param name="maxScreen">最大化视频窗口</param>
        /// <param name="doubleAction">共同的双击事件</param>
        public static void ShowMaxScreen(EnvVideoPanel selectedPanel,
            System.Windows.Controls.Panel splitScreen,
            EnvVideoPanel maxScreen, Action doubleAction = null)
        {
            try
            {
                if (selectedPanel == null || maxScreen == null)
                    return;

                EnvPanelOperation.SelectedPanel = selectedPanel;
                if (selectedPanel.Tag != null && selectedPanel.Tag is TagModel &&
                    string.IsNullOrWhiteSpace((selectedPanel.Tag as TagModel).Panel_RealPlayHandle))
                {
                    return; // 必须在播放情况下才能最大化
                }

                if (splitScreen != null)
                    splitScreen.Visibility = System.Windows.Visibility.Collapsed;
                if (maxScreen != null)
                    maxScreen.Visibility = System.Windows.Visibility.Visible;

                if (maxScreen.Tag == null)
                    maxScreen.Tag = new TagModel();

                EnvUtilities.StopAndPlay(selectedPanel, maxScreen);
                (maxScreen.DataContext as ViewModel_EnvVideoPanel).VideoInformation =
                    (selectedPanel.DataContext as ViewModel_EnvVideoPanel).VideoInformation; // 设置标题信息

                // 执行双击后的相关操作
                if (doubleAction != null)
                    doubleAction();
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 修改边框颜色
        /// </summary>
        /// <param name="selectedPanel">当前所选视频窗口</param>
        /// <param name="panelCurrentList">记录大屏新创建的 Panel 数组</param>
        public static void ChangeBorderColor(EnvVideoPanel selectedPanel,
            List<EnvVideoPanel> panelCurrentList)
        {
            try
            {
                if (selectedPanel == null)
                    return;

                // 去掉所有边框颜色
                if (panelCurrentList != null)
                {
                    foreach (EnvVideoPanel currPanel in panelCurrentList)
                    {
                        (currPanel.DataContext as ViewModel_EnvVideoPanel).BorderColor =
                            new SolidColorBrush(Colors.Transparent); // 无色
                    }
                }

                EnvPanelOperation.SelectedPanel = selectedPanel;
                (EnvPanelOperation.SelectedPanel.DataContext as ViewModel_EnvVideoPanel).BorderColor =
                    new SolidColorBrush(Colors.LimeGreen); // 高亮当前视频窗口
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }

        /// <summary>
        /// 修改边框颜色【针对回放界面】
        /// </summary>
        /// <param name="selectedPanel">当前所选视频窗口</param>
        /// <param name="panelCurrentList">记录大屏新创建的 Panel 数组</param>
        public static void ChangeBorderColor4Preview(EnvVideoPanel selectedPanel,
            List<EnvVideoPanel> panelCurrentList)
        {
            try
            {
                if (selectedPanel == null)
                    return;

                // 去掉所有边框颜色
                if (panelCurrentList != null)
                {
                    foreach (EnvVideoPanel currPanel in panelCurrentList)
                    {
                        (currPanel.DataContext as ViewModel_EnvVideoPanel).BorderColor =
                            new SolidColorBrush(Colors.Transparent); // 无色
                    }
                }

                EnvPanelOperationExt.SelectedPanel = selectedPanel;
                (EnvPanelOperationExt.SelectedPanel.DataContext as ViewModel_EnvVideoPanel).BorderColor =
                    new SolidColorBrush(Colors.LimeGreen); // 高亮当前视频窗口
            }
            catch (System.Exception ex)
            {
#if DEBUG
                Debug.WriteLine(ex.Message);
#endif
            }
        }



        /// <summary>
        /// 流数据录像
        /// </summary>
        /// <param name="selectedPanel">当前所选视频窗口</param>
        public static void RecordVideo(EnvVideoPanel selectedPanel)
        {
            if (EnvEventAggregator != null && selectedPanel != null &&
                selectedPanel.Tag != null && selectedPanel.Tag is TagModel &&
                (selectedPanel.Tag as TagModel).Driver_Instance != null &&
                !string.IsNullOrWhiteSpace((selectedPanel.Tag as TagModel).Panel_SelectedChannel))
            { 
                EnvEventAggregator.GetEvent<OpenModelEvent>().Publish(new OpenModelEventArg() { ModelName = "VideoMgtModule", FunctionName = "RecordVideo", Arg = selectedPanel, }); // 事件通知
            }
        }

        /// <summary>
        /// 远程录像回放
        /// </summary>
        /// <param name="selectedPanel">当前所选视频窗口</param>
        public static void PlayBack(EnvVideoPanel selectedPanel)
        {
            if (EnvEventAggregator != null && selectedPanel != null &&
                selectedPanel.Tag != null && selectedPanel.Tag is TagModel)
            {
                EnvEventAggregator.GetEvent<OpenModelEvent>().Publish(new OpenModelEventArg() { ModelName = "ToolkitMgtModule", FunctionName = "PlayBack", Arg = selectedPanel, }); // 事件通知
            }
        }

        /// <summary>
        /// 视频窗口截图
        /// </summary>
        /// <param name="selectedPanel">当前所选视频窗口</param>
        /// <param name="saveScreenShotPath">截图保存路径</param>
        public static void ScreenShot(EnvVideoPanel selectedPanel, string saveScreenShotPath = null)
        {
            if (EnvEventAggregator != null && selectedPanel != null &&
                selectedPanel.Tag != null && selectedPanel.Tag is TagModel &&
                (selectedPanel.Tag as TagModel).Driver_Instance != null &&
                !string.IsNullOrWhiteSpace((selectedPanel.Tag as TagModel).Panel_RealPlayHandle))
            {
                ArgModel arg = new ArgModel()
                {
                    obj1 = selectedPanel,
                    obj2 = saveScreenShotPath,
                };
                EnvEventAggregator.GetEvent<OpenModelEvent>().Publish(new OpenModelEventArg() { ModelName = "VideoMgtModule", FunctionName = "ScreenShot", Arg = arg, }); // 事件通知
            }
        }

        #endregion
    }
}
